﻿using _220105BookSys.api.Tools;
using _220105BookSys.api.Tools.QueryParam;
using _220105BookSys.Dto.BookType;
using _220105BookSys.IRepository;
using _220105BookSys.Model;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace _220105BookSys.api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class BookTypeController : ControllerBase
    {
        //private readonly ILogger logger;
        private readonly IBookRepository bookRepository;
        private readonly IBookTypeRepository bookTypeRepository;
        private readonly IMapper mapper;

        public BookTypeController(IBookRepository bookRepository,IBookTypeRepository bookTypeRepository,IMapper mapper)
        {
            
            this.bookRepository = bookRepository;
            this.bookTypeRepository = bookTypeRepository;
            this.mapper = mapper;
        }

        #region Get
        ///Get All BookType
        [HttpGet]
        public async Task<IActionResult> Get()
        {
            var result = await bookTypeRepository.GetBookTypesAsync();
            return Ok(mapper.Map<List<BookTypeDto>>(result));
        }

        /// <summary>
        /// Get By Paged
        /// </summary>
        /// <returns></returns>
        [HttpGet("Paged")]
        public async Task<IActionResult> GetPaged([FromQuery]Pagination pagination)
        {
            pagination.Total = await bookTypeRepository.GetTotalAsync();
            if (pagination.Total<=0)
            {
                return NoContent();
            }
            var result = await bookTypeRepository.GetBookTypesAsync(pagination.PageIndex,pagination.PageSize);
            pagination.Data = mapper.Map<List<BookTypeDto>>(result);
            
            return Ok(pagination);
        }

        /// <summary>
        /// Get By Paged
        /// </summary>
        /// <returns></returns>
        [HttpGet("Query")]
        public async Task<IActionResult> GetByQuery([FromQuery] BookTypeQuery bookTypeQuery)
        {
            var result = await bookTypeRepository.GetBookTypesAsync();
            //判断各个选项是否为空，如果不为空，则执行对应的条件查询
            if (bookTypeQuery.Id!=null|| bookTypeQuery.Id.ToString()!="")
            {
                result= result.Where(b => b.Id.Equals(bookTypeQuery.Id));
            }
            if (bookTypeQuery.Name!=null||bookTypeQuery.Name!="")
            {
                result= result.Where(b => b.Name.Contains(bookTypeQuery.Name));
            }
            return Ok(mapper.Map<List<BookTypeDto>>(result));
        }


        /// <summary>
        /// Get By Paged and Query
        /// </summary>
        /// <returns></returns>
        [HttpGet("QueryAndPaged")]
        public async Task<IActionResult> GetByQueryAndPaged([FromQuery] BookTypeQuery bookTypeQuery, [FromQuery] Pagination pagination)
        {
            var result = await bookTypeRepository.GetBookTypesAsync();
            //判断各个选项是否为空，如果不为空，则执行对应的条件查询
            if (bookTypeQuery.Id.ToString() != null && bookTypeQuery.Id.ToString() != "")
            {
                result = result.Where(b => b.Id.Equals(bookTypeQuery.Id));
            }
            if (bookTypeQuery.Name != null && bookTypeQuery.Name != "")
            {
                result = result.Where(b => b.Name.Contains(bookTypeQuery.Name));
            }
            if (bookTypeQuery.BookName!=null&&bookTypeQuery.BookName!="")
            {
                result = result.Where(b => {
                    foreach (var item in b.Books)
                    {
                        if (item.Name.Equals(bookTypeQuery.BookName))
                        {
                            return true;
                        }
                    }
                    return false;
                });
            }

            //手动分页
            pagination.Total = result.Count();
            if (pagination.Total<=0)
            {
                return NoContent();
            }
            result= result.Skip((pagination.PageIndex - 1) * pagination.PageSize).Take(pagination.PageSize).ToList();
            pagination.Data = mapper.Map<List<BookTypeDto>>(result);

            return Ok(pagination);
        }

        /// <summary>
        /// Get Single
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}",Name = "GetSingle")]
        public async Task<IActionResult> GetSingle([FromRoute] Guid id)
        {
            var result = await bookTypeRepository.GetBookTypeAsync(id);
            if (result == null)
            {
                return NotFound("未找到指定对象！");
            }
            return Ok(mapper.Map<BookTypeDto>(result));
        }

        #endregion

        #region Create
        /// <summary>
        /// Create
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> Create([FromBody]BookTypeDtoForCreatation bookTypeDtoForCreatation)
        {
            
            var bookType = mapper.Map<BookType>(bookTypeDtoForCreatation);
            //进一步封装id，因为用户在添加时肯定不知道该提供什么样的Guid
            foreach (var item in bookType.Books)
            {
                item.Id = Guid.NewGuid();
                item.BookTypeId = bookType.Id;
            }
            var result=await this.bookTypeRepository.CreateAsync(bookType);
            if (result)
            {
                return CreatedAtRoute(nameof(GetSingle), new { id = bookType.Id }, mapper.Map<BookTypeDto>(bookType));
            }
            else return BadRequest("服务器错误，添加失败！");
        }
        #endregion

        #region Update
        /// <summary>
        /// Update By HttpPut
        /// </summary>
        /// <returns></returns>
        [HttpPut("{bookTypeId}")]
        public async Task<IActionResult> Update([FromRoute]Guid bookTypeId, [FromBody] BookTypeDtoForPutUpdate bookTypeDtoForPutUpdate)
        {
            //1、先找到指定的对象，
            var targetBookType =await bookTypeRepository.GetBookTypeAsync(bookTypeId);
            if (targetBookType==null)
            {
                return NotFound("未找到指定对象！");
            }
            //2、再更新指定对象的指定更改了的数据
            targetBookType.Name = bookTypeDtoForPutUpdate.Name;
            //3、执行Update
            var result = await bookTypeRepository.UpdateAsync(targetBookType);
            if (result)
            {
                return Ok(targetBookType);
            }
            else return BadRequest("服务器错误，修改失败！");
            
        }


        /// <summary>
        /// Update By HttpPatch
        /// </summary>
        /// <returns></returns>
        [HttpPatch]
        public async Task<IActionResult> UpdatePatch([FromRoute] Guid bookTypeId, [FromBody] BookTypeDtoForPutUpdate bookTypeDtoForPutUpdate)
        {
            //1、先找到指定的对象，
            var targetBookType = await bookTypeRepository.GetBookTypeAsync(bookTypeId);
            if (targetBookType == null)
            {
                return NotFound("未找到指定对象！");
            }
            //2、再更新指定对象的指定更改了的数据
            targetBookType.Name = bookTypeDtoForPutUpdate.Name;
            //3、执行Update
            var result = await bookTypeRepository.UpdateAsync(targetBookType);
            if (result)
            {
                return Ok(targetBookType);
            }
            else return BadRequest("服务器错误，修改失败！");

        }
        #endregion

        #region Delete
        /// <summary>
        /// Create
        /// </summary>
        /// <returns></returns>
        [HttpDelete("{bookTypeId}")]
        public async Task<IActionResult> Delete([FromRoute] Guid bookTypeId)
        {

            //1、判断是否存在
            if (!await bookTypeRepository.IsExsitedAsync(bookTypeId))
            {
                return NotFound("未找到指定对象！");
            }
            //2、删除对象
            var result = await bookTypeRepository.RealDeleteAsync(bookTypeId);
            //return result ? NoContent() : BadRequest("服务器错误，删除失败！");
            if (result)
            {
               return NoContent();
            }
            return BadRequest("服务器错误，删除失败！");
        }
        #endregion

    }
}
